home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / DJSRC111.ZIP / go32 / grprot.asm < prev    next >
Assembly Source File  |  1993-08-13  |  14KB  |  402 lines

  1. ;;
  2. ;; This is file GRPROT.ASM
  3. ;;
  4. ;; Copyright (C) 1993 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  5. ;; Copyright (C) 1993 Csaba Biegl, csaba@vuse.vanderbilt.edu
  6. ;; Copyright (C) 1993 Grzegorz Mazur, gbm@ii.pw.edu.pl
  7. ;;
  8. ;; This file is distributed under the terms listed in the document
  9. ;; "copying.dj", available from DJ Delorie at the address above.
  10. ;; A copy of "copying.dj" should accompany this file; if not, a copy
  11. ;; should be available from where this file was obtained.  This file
  12. ;; may not be distributed without a verbatim copy of "copying.dj".
  13. ;;
  14. ;; This file is distributed WITHOUT ANY WARRANTY; without even the implied
  15. ;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. ;;
  17.  
  18. ;    History:270,22
  19.     title    grprot
  20.     .386p
  21.  
  22.     include segdefs.inc
  23.     include tss.inc
  24.     include gdt.inc
  25.     include idt.inc
  26.  
  27. ;------------------------------------------------------------------------
  28. ;
  29. ;  Memory Map (relative to 0xe0000000) :
  30. ;    00000000 - 000fffff == read/write area
  31. ;    00100000 - 001fffff == read only area
  32. ;    00200000 - 002fffff == write only area
  33. ;    01000000 - 01ffffff == 16MB read/write area
  34. ;    02000000 - 02ffffff == 16MB read only area
  35. ;    03000000 - 03ffffff == 16MB write only area
  36. ;
  37. ;  If your board can support separate read & write mappings,
  38. ;  like the TSENG chips, then either one of two cases applies:
  39. ;  1. The read and write mappings are the same, and the rw, r,
  40. ;     and w areas all have one present bank.
  41. ;  2. The read and write mappings are different, and only the
  42. ;     r and w areas have a mapped bank.  Accesses to the rw area
  43. ;     cause a page fault and the board goes back into case #1.
  44. ;
  45. ;  If your board can't support separate read & write mappings,
  46. ;  always map the rw, r, and w areas to the same page (case #1 above)
  47. ;
  48. ;  It is up to the programmer to ensure that the program doesn't
  49. ;  read from the write only area, or write to the read only area.
  50. ;
  51. ;  This method is used because you can't use the string move instructions
  52. ;  across pages.  The "movsx" instruction causes *two* memory references,
  53. ;  potentially to different banks.  The first causes one bank to be
  54. ;  enabled, and the instruction is restarted.  The second access causes
  55. ;  the second bank to be enabled, and the instruction is *RESTARTED*.
  56. ;  This means it will attempt the *first* access again, causing it to be
  57. ;  enabled, ad infinitum.
  58. ;
  59. ;  Thus, bcopy() and memcpy() shouldn't *ever* access the rw area!
  60. ;
  61. ;------------------------------------------------------------------------
  62.  
  63.     extrn    _graphics_pt1_lin:dword            ; page table #1
  64.     extrn    _graphics_pt2_lin:dword            ; page table #2
  65.     extrn    _graphics_pt1_loc:word            ; current location of page table #1
  66.     extrn    _graphics_pt2_loc:word            ; current location of page table #2
  67.     extrn    _graphics_pd_lin:dword            ; ptr to graphics section of PD
  68.     extrn    _graphics_pd_seg_lin:dword        ; ptr to graphics section of Pseg Dir
  69.  
  70.     extrn    _gr_paging_func:dword            ; the paging function
  71.  
  72.     extrn    _gr_r_w_page_size:dword            ; read or write only page size in 4K units
  73.     extrn    _gr_sgl_page_size:dword            ; R/W page size in 4K units
  74.     extrn    _gr_r_w_page_shift:byte            ; log2 of read or write only page size/4K
  75.     extrn    _gr_sgl_page_shift:byte            ; log2 of R/W page size/4K
  76.     extrn    _gr_rw_page_offset:byte            ; diff between pages in R/W mode (ATI!)
  77.  
  78.     extrn    _gr_rw_table_lin:dword            ; prepared R/W page table section
  79.     extrn    _gr_ro_table_lin:dword            ; prepared read only page table section
  80.     extrn    _gr_wo_table_lin:dword            ; prepared write only page table section
  81.  
  82. ;;
  83. ;; current and previous paging mode codes:
  84. ;;
  85. BIGPAGE        equ    2
  86. SINGLE        equ    4
  87. WRFAULT        equ    8
  88.  
  89. mode_r_w    equ    0                ; split 1M  pages
  90. mode_r_w_big    equ    mode_r_w + BIGPAGE        ; split 16M pages
  91. mode_sgl    equ    SINGLE                ; single 1M  R/W page
  92. mode_sgl_big    equ    mode_sgl + BIGPAGE        ; single 16M R/W page
  93. mode_rr_w    equ    mode_r_w            ; split 1M:  read fault
  94. mode_rr_w_big    equ    mode_r_w_big            ; split 16M: read fault
  95. mode_r_ww    equ    mode_r_w     + WRFAULT        ; split 1M:  write fault (current only)
  96. mode_r_ww_big    equ    mode_r_w_big + WRFAULT        ; split 16M: write fault (current only)
  97.  
  98.     start_data16
  99.  
  100. cur_p    dw    0                    ; current mapped r/w or read only page
  101. cur_w    dw    0                    ; current mapped write only page
  102. mode    dw    mode_sgl                ; current paging mode
  103. VGA_w    db    0                    ; current VGA write page
  104. VGA_r    db    0                    ; current VGA read page
  105.  
  106.     end_data16
  107.  
  108. ;------------------------------------------------------------------------
  109. ;
  110. ; the graphics page fault routine
  111. ;
  112. ;------------------------------------------------------------------------
  113.     start_code16
  114.  
  115.     extrn    _page_fault:near
  116.     public  graphics_fault
  117.  
  118. graphics_fault:
  119.     cli
  120.     cld
  121.     mov    ax,g_core
  122.     mov    es,ax
  123.     mov    ebx,cr2
  124.  
  125.     shr    ebx,20                ; bx: fault loc/1Meg
  126.     mov    dx,bx
  127.     shr    dx,2                ; dx: fault loc/4Meg
  128.     and    bx,03h                ; mask multiple of 1MB  bits (0..3)
  129.     and    dx,0ch                ; mask multiple of 16MB bits (0..3)
  130.     or    bx,dx
  131.  
  132. ;    shr    ebx,10
  133. ;    shr    bh,2
  134. ;    shr    bx,10
  135.  
  136.     mov    bl,cs:mode_table[bx]
  137.     mov    bp,bx                ; bp: new paging mode
  138.     lea    si,_graphics_pt1_loc        ; check page table position in pg dir
  139.     cmp    bp,mode_r_ww_big
  140.     jne    check_pgdir
  141.     lea    si,_graphics_pt2_loc        ; here we need the second page table
  142. check_pgdir:
  143.     mov    ax,[si]
  144.     mov    ebx,cr2
  145.     shr    ebx,22
  146.     and    bx,(03ffffffh SHR 22)
  147.     cmp    ax,bx                ; ax: old, bx: new
  148.     je    pgdir_done
  149.     and    eax,0000ffffh
  150.     xor    edx,edx
  151.     mov    edi,_graphics_pd_lin
  152.     mov    ecx,es:[edi+eax*4]        ; move page table
  153.     mov    es:[edi+ebx*4],ecx
  154.     mov    es:[esi+eax*4],edx        ; zero old entry
  155.     mov    edi,_graphics_pd_seg_lin
  156.     mov    cl,es:[edi+eax]            ; move page table segment
  157.     mov    es:[edi+ebx],cl
  158.     mov    es:[edi+eax],dl            ; zero old entry
  159.     mov    [si],bx
  160. pgdir_done:
  161.     mov    edx,cr2
  162.     shr    edx,12
  163.     and    dx,(03ffffffh SHR 12)        ; dx: page index where fault occurred
  164.     mov    bx,dx                ; bx: VGA page in 4kByte units
  165.     and    bx,(00ffffffh SHR 12)        ; mask out 16MB region indicators
  166.     jmp    cs:pginv_table[bp]
  167.  
  168. pginv_table    label word            ; dispatch to invalidate old page table(s)
  169.     dw    offset invalidate_rr_w
  170.     dw    offset invalidate_rr_w_big
  171.     dw    offset invalidate_sgl
  172.     dw    offset invalidate_sgl_big
  173.     dw    offset invalidate_r_ww
  174.     dw    offset invalidate_r_ww_big
  175.  
  176. mode_table    label byte            ; table of paging modes depending on addr
  177.     db    mode_sgl
  178.     db    mode_rr_w
  179.     db    mode_r_ww
  180.     db    -1                ; should never need this!!!
  181.     db    mode_sgl_big
  182.     db    mode_sgl_big
  183.     db    mode_sgl_big
  184.     db    mode_sgl_big
  185.     db    mode_rr_w_big
  186.     db    mode_rr_w_big
  187.     db    mode_rr_w_big
  188.     db    mode_rr_w_big
  189.     db    mode_r_ww_big
  190.     db    mode_r_ww_big
  191.     db    mode_r_ww_big
  192.     db    mode_r_ww_big
  193.  
  194. invalidate_rr_w:                ; split page: read fault
  195.     and    bx,(000fffffh SHR 12)        ; mask out 1MB region indicator
  196. invalidate_rr_w_big:
  197.     mov    cl,_gr_r_w_page_shift
  198.     shr    dx,cl                ; truncate page to VGA limits
  199.     shl    dx,cl
  200.     and    bx,(00ffffffh SHR 12)        ; mask out 16MB region indicator
  201.     shr    bx,cl                ; figure out VGA page
  202.     mov    VGA_r,bl
  203.     mov    edi,_graphics_pt1_lin        ; edi: zero in this page table
  204.     mov    ecx,edi                ; ecx: copy to this page table
  205.     mov    esi,_gr_ro_table_lin        ; esi: copy from this prepared table
  206.     mov    ebx,_gr_r_w_page_size        ; ebx: copy this many entries
  207.     mov    ax,cur_p            ; ax:  zero from this position
  208.     mov    cur_p,dx            ; dx:  copy here, also updated mapping index
  209.     jmp    invalidate_ptable
  210.  
  211. invalidate_r_ww:                ; split page: write fault
  212.     and    bx,(000fffffh SHR 12)        ; mask out 1MB region indicator
  213. invalidate_r_ww_big:
  214.     mov    cl,_gr_r_w_page_shift
  215.     shr    dx,cl                ; truncate page to VGA limits
  216.     shl    dx,cl
  217.     and    bx,(00ffffffh SHR 12)        ; mask out 16MB region indicator
  218.     shr    bx,cl                ; figure out VGA page
  219.     mov    VGA_w,bl
  220.     mov    ecx,_graphics_pt1_lin        ; ecx: copy to this page table
  221.     mov    esi,_gr_wo_table_lin        ; esi: copy from this prepared table
  222.     mov    ebx,_gr_r_w_page_size        ; ebx: copy this many entries
  223.     mov    ax,cur_w            ; ax:  zero from this position
  224.     mov    cur_w,dx            ; dx:  copy here, also updated mapping index
  225.     test    bp,BIGPAGE            ; is ptable1 correct?
  226.     je    invalidate_r_ww_dispatch
  227.     mov    ecx,_graphics_pt2_lin        ; ecx: copy to this page table
  228. invalidate_r_ww_dispatch:
  229.     mov    di,mode
  230.     jmp    cs:inv_r_ww_oldmd[di]        ; figure out how to invalidate based on old mode
  231. inv_r_ww_oldmd  label word
  232.     dw    inv_r_ww_old_r_w
  233.     dw    inv_r_ww_old_r_w_big
  234.     dw    inv_r_ww_old_sgl
  235.     dw    inv_r_ww_old_sgl_big
  236. inv_r_ww_old_r_w:
  237.     mov    edi,_graphics_pt1_lin        ; edi: zero in this page table
  238.     jmp    invalidate_ptable
  239. inv_r_ww_old_r_w_big:
  240.     mov    edi,_graphics_pt2_lin        ; edi: zero in this page table
  241.     jmp    invalidate_ptable
  242. inv_r_ww_old_sgl:
  243. inv_r_ww_old_sgl_big:
  244.     mov    edi,_graphics_pt1_lin        ; edi: zero in this page table
  245.     mov    ax,cur_p            ; ax:  zero from this position
  246.     jmp    invalidate_ptable
  247.  
  248. invalidate_sgl:
  249. invalidate_sgl_big:
  250.     test    mode,SINGLE
  251.     jne    invalidate_one_table_only
  252.     mov    edi,_graphics_pt1_lin
  253.     test    mode,BIGPAGE
  254.     je    invalidate_wr_ptable
  255.     mov    edi,_graphics_pt2_lin
  256. invalidate_wr_ptable:
  257.     mov    cx,cur_w
  258.     and    ecx,1023
  259.     lea    edi,[edi+ecx*4]
  260.     mov    ecx,_gr_r_w_page_size
  261.     xor    eax,eax
  262.     rep
  263.     db    67h
  264.     stosd
  265. invalidate_one_table_only:
  266.     mov    cl,_gr_sgl_page_shift
  267.     shr    dx,cl                ; truncate page to VGA limits
  268.     shl    dx,cl
  269.     shr    bx,cl                ; figure out VGA pages
  270.     mov    cl,_gr_rw_page_offset        ; ATI style paging hack
  271.     shl    bl,cl
  272.     mov    VGA_w,bl
  273.     add    bl,cl
  274.     mov    VGA_r,bl
  275.     mov    edi,_graphics_pt1_lin        ; edi: zero in this page table
  276.     mov    ecx,edi                ; ecx: copy to this page table
  277.     mov    esi,_gr_rw_table_lin        ; esi: copy from this prepared table
  278.     mov    ebx,_gr_sgl_page_size        ; ebx: copy this many entries
  279.     mov    ax,cur_p            ; ax:  zero from this position
  280.     mov    cur_p,dx            ; dx:  copy here, also updated mapping index
  281.  
  282. invalidate_ptable:
  283.     and    eax,1023
  284.     lea    edi,[edi+eax*4]            ; edi: zero page table here
  285.     and    edx,1023
  286.     lea    edx,[ecx+edx*4]            ; edx: copy into page table here
  287.     mov    ecx,_gr_sgl_page_size        ; entries to clear at edi
  288.     test    bp,SINGLE            ; correct?
  289.     jne    clear_ptable
  290.     mov    ecx,_gr_r_w_page_size        ; now it is!
  291. clear_ptable:
  292.     xor    eax,eax
  293.     rep
  294.     db    67h
  295.     stosd
  296.     mov    edi,edx                ; copy into page table here
  297.     mov    ecx,ebx                ; this many entries
  298.     mov    dx,ds
  299.     mov    ax,g_core
  300.     mov    ds,ax
  301.     rep
  302.     db    67h
  303.     movsd
  304.     mov    ds,dx
  305.     and    bp,(SINGLE + BIGPAGE)        ; update mode
  306.     mov    mode,bp
  307.  
  308.     mov    ax,word ptr VGA_w
  309.     call    dword ptr [_gr_paging_func]    ; call paging func
  310.  
  311.     mov    eax,cr3
  312.     mov    cr3,eax
  313.  
  314.     pop    eax
  315.     iretd                    ; back to running program
  316.     jmp    _page_fault
  317.  
  318.     end_code16
  319.  
  320. ;------------------------------------------------------------------------
  321. ; Real mode paging assist code.
  322. ; The idea is that we have to call the driver's paging function in real
  323. ; mode. GRAPHICS.C's 'graphics_assist' function provides this service
  324. ; by intercepting the int 0x10, ah=0xff calls. Unfortunately we cannot
  325. ; issue this call from the paging task. Instead the paging routine only
  326. ; changes the arena task's eip to point to a routine which invokes
  327. ; int 10 first thing when the arena task resumes. A temporary buffer
  328. ; is used to save the arena task's eax and ebx. The same buffer
  329. ; holds the VGA page values. The virtual address of this buffer is passed
  330. ; to the arena task in the eax register. This solution was necessary because
  331. ; it is not certain what would happen if we got a second page fault here
  332. ; (for which there is a slight chance if we try to use the arena's stack).
  333. ; For safety the buffer also contains a busy flag which is cleared by
  334. ; the arena routine after completion. The arena task's state is not changed
  335. ; if this flag is set. The effect of this is that the VGA is not reprogrammed
  336. ; but a garbled screen is still much better than a crashed program! Anyway,
  337. ; this should not happen unless some smartass tries to do multitasking
  338. ; time-sliced graphics (did anyone say that the graphics libs were
  339. ; reentrant?)
  340. ;------------------------------------------------------------------------
  341.  
  342.     extrn    _real_paging_buffer_lin:dword    ; linear address the way I see it
  343.     extrn    _real_paging_buffer_virt:dword  ; address the way the arena sees it
  344.     extrn    _real_paging_func_virt:dword    ; arena address of the 'int 0x10' func
  345.     extrn    _a_tss:tss_s
  346.  
  347. start_code16
  348.  
  349.     public  _real_paging_routine
  350. _real_paging_routine proc far
  351.     mov    esi,_real_paging_buffer_lin
  352.     cmp    byte ptr es:[esi],0        ; busy ?
  353.     jne    paging_busy            ; note: this runs with IT-s disabled
  354.     mov    byte ptr es:[esi],1        ; so we can do this non-atomic stuff
  355.     mov    ebx,_a_tss.tss_eax
  356.     mov    es:[esi+4],ebx            ; save arena eax
  357.     mov    ebx,_a_tss.tss_ebx
  358.     mov    es:[esi+8],ebx            ; save arena ebx
  359.     mov    es:[esi+12],eax            ; put VGA page indices in buffer
  360.     mov    ebx,_a_tss.tss_eip
  361.     mov    _a_tss.tss_ebx,ebx        ; pass arena's old eip in ebx to it
  362.     mov    ebx,_real_paging_func_virt
  363.     mov    _a_tss.tss_eip,ebx        ; change arena eip
  364.     mov    ebx,_real_paging_buffer_virt
  365.     mov    _a_tss.tss_eax,ebx        ; pass buffer address in eax
  366. paging_busy:
  367.     ret
  368. _real_paging_routine endp
  369.  
  370.     end_code16
  371.  
  372. ;------------------------------------------------------------------------
  373. ; The real mode paging hook in the arena task.
  374. ;------------------------------------------------------------------------
  375. _TEXT32 segment dword public 'code' use32
  376.     assume  cs:_TEXT32,ds:nothing,ss:nothing
  377.  
  378.     public  _arena_real_paging_func
  379. _arena_real_paging_func:
  380.     push    ebx                ; save return address
  381.     pushf                    ; save flags
  382.     mov    ebx,[eax+4]
  383.     push    ebx                ; stack old eax
  384.     mov    ebx,[eax+8]
  385.     push    ebx                ; stack old ebx
  386.     mov    ebx,[eax+12]            ; VGA page indices
  387.     push    eax
  388.     mov    ax,0fffdh            ; 'graphics_assist' fnc code
  389.     int    10h
  390.     pop    eax
  391.     mov    byte ptr [eax],0        ; clear busy flag
  392.     pop    ebx
  393.     pop    eax
  394.     popf
  395.     ret
  396.  
  397. _TEXT32 ends
  398.  
  399. ;------------------------------------------------------------------------
  400.  
  401.     end
  402.